#include "../../mqserver/router.hpp"
#include "../../mqcommon/msg.pb.h"
#include <gtest/gtest.h>


class RouterTest : public testing::Environment
{
public:
    virtual void SetUp() override
    {
    }
    virtual void TearDown() override
    {
    }
};

// TEST(RouterTest, isLegalRoutingEey)
// {
//     std::string routingKey1 = "news.music.pop";
//     std::string routingKey2 = "news..music.pop";
//     std::string routingKey3 = "news.,music.pop";
//     std::string routingKey4 = "news.music_123.pop";
//     EXPECT_EQ(Router::isLegalRoutingKey(routingKey1), true);
//     EXPECT_EQ(Router::isLegalRoutingKey(routingKey2), true);
//     EXPECT_EQ(Router::isLegalRoutingKey(routingKey3), false);
//     EXPECT_EQ(Router::isLegalRoutingKey(routingKey4), true);
// }

// TEST(RouterTest, isLegalBindingEey)
// {
//     std::string bkey1 = "news.music.pop";
//     std::string bkey2 = "news.#.music.pop";
//     std::string bkey3 = "news.#.*.music.pop";
//     std::string bkey4 = "news.*.#.music.pop";
//     std::string bkey5 = "news.#.#.music.pop";
//     std::string bkey6 = "news.*.*.music.pop";
//     std::string bkey7 = "news.,music_123.pop";
//     EXPECT_EQ(Router::isLegalBindingKey(bkey1), true);
//     EXPECT_EQ(Router::isLegalBindingKey(bkey2), true);
//     EXPECT_EQ(Router::isLegalBindingKey(bkey3), false);
//     EXPECT_EQ(Router::isLegalBindingKey(bkey4), false);
//     EXPECT_EQ(Router::isLegalBindingKey(bkey5), false);
//     EXPECT_EQ(Router::isLegalBindingKey(bkey6), true);
//     EXPECT_EQ(Router::isLegalRoutingKey(bkey7), false);
// }

TEST(RouterTest, route)
{
// binding key               routing key              result
// aaa                       aaa                       true
// aaa.bbb                   aaa.bbb                   true
// aaa.bbb                   aaa.bbb.ccc               false
// aaa.bbb                   aaa.ccc                   false
// aaa.#.bbb                 aaa.bbb.ccc               false
// aaa.bbb.#                 aaa.ccc.bbb               false
// #.bbb.ccc                 aaa.bbb.ccc.ddd           false
// aaa.bbb.ccc               aaa.bbb.ccc               true
// aaa.*                     aaa.bbb                   true
// aaa.*.bbb                 aaa.bbb.ccc               false
// *.aaa.bbb                 aaa.bbb                   false
// #                         aaa.bbb.ccc               true
// aaa.#                     aaa.bbb                   true
// aaa.#                     aaa.bbb.ccc               true
// aaa.#.ccc                 aaa.ccc                   true
// aaa.#.ccc                 aaa.bbb.ccc               true
// aaa.#.ccc                 aaa.aaa.bbb.ccc           true
// #.ccc                     ccc                       true
// #.ccc                     aaa.bbb.ccc               true
// aaa.#.ccc.ccc             aaa.bbb.ccc.ccc.ccc       true
// aaa.#.bbb.*.bbb           aaa.ddd.ccc.bbb.eee.bbb   true
    std::vector<std::string> bindingKeys = {
        "aaa",            
        "aaa.bbb",        
        "aaa.bbb",        
        "aaa.bbb",        
        "aaa.#.bbb",      
        "aaa.bbb.#",      
        "#.bbb.ccc",      
        "aaa.bbb.ccc",    
        "aaa.*",          
        "aaa.*.bbb",      
        "*.aaa.bbb",      
        "#",              
        "aaa.#",          
        "aaa.",          
        "aaa.#.ccc",      
        "aaa.#.ccc",      
        "aaa.#.ccc",      
        "#.ccc",          
        "#.ccc",          
        "aaa.#.ccc.ccc",  
        "aaa.#.bbb.*.bbb"
    };
    
    std::vector<std::string> routingKeys = {
        "aaa",                    
        "aaa.bbb",                
        "aaa.bbb.ccc",            
        "aaa.ccc",                
        "aaa.bbb.ccc",            
        "aaa.ccc.bbb",            
        "aaa.bbb.ccc.ddd",        
        "aaa.bbb.ccc",            
        "aaa.bbb",                
        "aaa.bbb.ccc",            
        "aaa.bbb",                
        "aaa.bbb.ccc",            
        "aaa.bbb",                
        "aaa.bbb.ccc",            
        "aaa.ccc",                
        "aaa.bbb.ccc",            
        "aaa.aaa.bbb.ccc",        
        "ccc",                    
        "aaa.bbb.ccc",            
        "aaa.bbb.ccc.ccc.ccc",    
        "aaa.ddd.ccc.bbb.eee.bbb",
    };
    
    std::vector<bool> results = {
        true,
        true,
        false,
        false,
        false,
        false,
        false,
        true,
        true,
        false,
        false,
        true,
        true,
        true,
        true,
        true,
        true,
        true,
        true,
        true,
        true
    };
    // DLOG("%ld,%ld,%ld", bindingKeys.size(), routingKeys.size(), results.size());
    // for(int i = 0; i < bindingKeys.size(); i++)
    // {
    //     DLOG("%d:%s,%s", i, routingKeys[i].c_str(), bindingKeys[i].c_str());
    //     EXPECT_EQ(Router::route(ExchangeType::TOPIC, routingKeys[i], bindingKeys[i]), results[i]);
    // }
    // EXPECT_EQ(Router::route(ExchangeType::TOPIC, "aaa.bbb.ccc.ccc.ccc", "aaa.#.ccc.ccc"), true);
}


int main(int argc, char* argv[])
{
    testing::InitGoogleTest(&argc, argv);
    testing::AddGlobalTestEnvironment(new RouterTest);

    return RUN_ALL_TESTS(); 
}